<?php
class PostCaptchaException extends WException {}	//	보안코드에러
class PostAlreadyReportedException extends WException {}	//	
class Cl_Post extends WdkClass 
{
	protected
		/******************************************************/
		//	원본 테이블 정보
		/******************************************************/
		$post_seq			= 0			,	//
		$fk_bbs_seq			= 0			,	//	
		$fk_category_seq	= 0			,	//	
		$fk_user_seq		= 0			,	//	
		$post_ref_url		= ''		,	//	
		$post_title			= ''		,	//	
		$post_content		= ''		,	//	
		$post_files			= array()	,	//	
		$post_secure_flag	= 'F'		,	//	
		$post_notice_flag	= 'F'		,	//	
		$post_agree			= 0			,	//	
		$post_opposite		= 0			,	//	
		$post_hits			= 0			,	//	
		$post_tag			= ''		,	//		
		$post_option_field1	= ''		,	//		
		$post_option_field2	= ''		,	//		
		$post_option_field3	= ''		,	//		
		$post_option_field4	= ''		,	//		
		$post_option_field5	= ''		,	//		
		$post_poll_flag		= 'F'		,	//		
		$post_poll_title	= ''		,	//		
		$post_poll_items	= array()	,	//		
		$post_moveup_count	= 0			,	//		
		$post_moveup_time	= 0			,	//		
		$post_report_count	= 0			,	//	
		$post_insert_time	= 0			,	//	
		$post_insert_ip		= ''		,	//	
		$post_del_flag		= 'F'		,	//	
		/******************************************************/
		//	추가 정보
		/******************************************************/	
		$bbs_id					= ''		,	//			
		$bbs_name				= ''		,	//			
		$comment_num			= ''		,	//		
		$category_name			= ''		,	//	
		$user_name				= 0			,	//	
		$user_nick				= 0			,	//	
		$user_nick_str			= ''		,	//	
		$user_login_id			= ''		,	//		
		$user_icon				= ''		,	//	
		$post_insert_time_str	= ''		,	//
		$post_insert_ip_str		= ''		,	//	
		$post_title_str			= ''		,	//	
		$post_tags				= array()	;	//	
	
	/**
	 * 	
	 */
	function __construct()
	{
		parent::__construct();
		self::getDbo();
	}
	
	/**
	 *	
	 */
	public function __init($data)
	{
		parent::__init($data);
		self::dformat();
	}
	
	/**
	 *	
	 */
	public function load($post_seq, $bbs=null)
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		if($bbs !== null && is_object($bbs))
		{
			$this->bbs = $bbs;
		}
		self::__init($dbo->cLoad($post_seq));
	}
	
	/**
	 *	
	 */
	public function dformat()
	{
		$this->post_ref_url			= htmlspecialchars($this->post_ref_url);
		$this->post_title			= htmlspecialchars($this->post_title);
		$this->post_tag				= htmlspecialchars($this->post_tag);
		$this->post_option_field1	= htmlspecialchars($this->post_option_field1);
		$this->post_option_field2	= htmlspecialchars($this->post_option_field2);
		$this->post_option_field3	= htmlspecialchars($this->post_option_field3);
		$this->post_option_field4	= htmlspecialchars($this->post_option_field4);
		$this->post_option_field5	= htmlspecialchars($this->post_option_field5);
		$this->post_poll_title		= htmlspecialchars($this->post_poll_title);
		
		if(is_string($this->post_files))
		{
			$this->post_files = (array) json_decode($this->post_files, 1);
		}
		if($this->post_moveup_time > 0)
		{
			$this->post_insert_time_str = parent::timeString($this->post_moveup_time);			
		}
		else
		{	
			$this->post_insert_time_str = parent::timeString($this->post_insert_time);
		}
		$this->post_insert_ip_str	= parent::ipString($this->post_insert_ip);
		$this->user_nick_str = $this->user_nick;
		if($this->user_icon)
		{
			$this->user_nick_str = "<img src='{$this->user_icon}' class='user_icon'/>";
		}
		if($this->post_report_count > 3)
		{
			$this->post_title_str = "신고 누적횟수 3회로 인하여 해당 게시물은 접근 차단되었습니다.";
		}
		$this->post_tags = explode(',', $this->post_tag);
		if(empty($this->post_tags) == false)
		{
			foreach($this->post_tags as $i=>$tag)	$this->post_tags[$i] = trim($tag);
		}
	}
	
	/**
	 * 
	 */
	public function autoUpdate($log='')
	{
		if((int)$this->post_seq > 0)
		{
			$this->update($log);
		}
		else
		{
			$this->insert($log);
		}
	}
	
	/**
	 * 
	 */
	public function setTitleLength($length=0, $tail="...")
	{
		$this->post_title_str		= iconv_substr($this->post_title, 0, $length, "UTF-8");
		if($this->post_title_str != $this->post_title)
		{
			$this->post_title_str.= $tail;
		} 
	}
	public function isEditable()
	{
		if($this->bbs->isAdmin()
		|| ($this->bbs['session']['is_login'] == 1 && $this->bbs['session']['user_seq'] == $this->fk_user_seq))
		{
			return true;
		}
		return false;
	}
	public function isReactable()
	{
		if($this->bbs['bbs_recommend_flag'] == 'T'
		&& $this->bbs['session']['is_login'] == true
		&& $this->bbs['session']['user_seq'] != $this->fk_user_seq)
		{
			try
			{
				$bpr = Wdk::get('PostReact');
				$bpr->loadByPost($this->post_seq, $this->bbs['session']['user_seq']);
			}
			catch(NoRecordException $e)
			{
				return true;
			}
		}
		return false;
	}
	public function isScrapable()
	{
		if($this->bbs['bbs_scrap_flag'] == 'T'
		&& $this->bbs['session']['is_login'] == true
		&& $this->bbs['session']['user_seq'] != $this->fk_user_seq)
		{
			try
			{
				$us = Wdk::get('UserScrap');
				$us->loadByPost($this->post_seq, $this->bbs['session']['user_seq']);
			} catch(NoRecordException $e) {return true;}
		}
		return false;
	}
	public function isMoveUpable()
	{
		if($this->bbs['bbs_moveup_flag'] == 'T'
		&& $this->bbs['session']['is_login'] == true
		&& $this->bbs['session']['user_seq'] == $this->fk_user_seq
		&& $this->post_moveup_count < 4)	//	3회까지 끌어올리기 가능..
		{
			if($this->post_moveup_count == 0)
			{
				//	등록후 하루지나기전엔 처음 끌어올리기 가능..
				if( $this->post_insert_time+24*3600 > mktime())
					return true;
			}
			else
			{
				//	끌어올린지 1시간이 안지나면 끌어올리기 불가능..
				if($this->post_moveup_time + 1*3600 > mktime())
				{
					return false;
				}
				//	끌어올린지 3시간이 지나면 끌어올리기 가능..
				if($this->post_moveup_time+3*3600 > mktime())
				{
					return true;
				}
			}	
		}
		return false;
	}
	
	/**
	 *	
	 */
	public function insert($log='Insert')
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		
		$this->post_agree			= 0;
		$this->post_opposite		= 0;
		$this->post_insert_time		= time();
		$this->post_moveup_time		= $this->post_insert_time;
		$this->post_moveup_count	= 0;
		$this->post_del_flag		= 'F';
		$this->post_report_count	= 0;
		$this->validate();
		$data = array(	'fk_bbs_seq'			=>	$this->fk_bbs_seq,
						'fk_category_seq'		=>	$this->fk_category_seq,
						'fk_user_seq'			=>	$this->fk_user_seq,
						'post_ref_url'			=>	$this->post_ref_url,
						'post_title'			=>	strip_tags($this->post_title),
						'post_content'			=>	$this->post_content,
						'post_files'			=>	json_encode((array)$this->post_files),
						'post_secure_flag'		=>	$this->post_secure_flag,
						'post_notice_flag'		=>	$this->post_notice_flag,
						'post_agree'			=>	$this->post_agree,
						'post_opposite'			=>	$this->post_opposite,
						'post_hits'				=>	$this->post_hits,
						'post_tag'				=>	$this->post_tag,
						'post_option_field1'	=>	$this->post_option_field1,
						'post_option_field2'	=>	$this->post_option_field2,
						'post_option_field3'	=>	$this->post_option_field3,
						'post_option_field4'	=>	$this->post_option_field4,
						'post_option_field5'	=>	$this->post_option_field5,
						'post_poll_flag'		=>	$this->post_poll_flag,
						'post_poll_title'		=>	$this->post_poll_title,
						'post_poll_items'		=>	json_encode((array)$this->post_poll_items),
						'post_moveup_count'		=>	$this->post_moveup_count,
						'post_moveup_time'		=>	$this->post_moveup_time,
						'post_report_count'		=>	$this->post_report_count,
						'post_insert_time'		=>	$this->post_insert_time,
						'post_insert_ip'		=>	isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',
						'post_del_flag'			=>	$this->post_del_flag
					);
		$this->post_seq = $dbo->insert($data);
		/******************************************************/
		parent::setBackupData(array_keys($data));
		$this->backup($log);
		/******************************************************/
		
		//	게시판 정보 
		$bbs = Wdk::get('Bbs');
		$bbs->load($this->fk_bbs_seq);
		
		/******************************************************************
		 포인트 적립
		*******************************************************************/
		if($bbs['bbs_write_point'] > 0)
		{	
			$up = Wdk::get('UserPoint');
			$up->plus(	$this->fk_user_seq,
						$bbs['bbs_write_point'],
						"[".$bbs['bbs_name']."] 게시물 등록 ($this->post_seq)"
						);
		}
		/*******************************************************************/
		$this->updateTag();
	}
	
	/**
	 * 
	 */
	public function update($log='update')
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		$pwd = Wdk::helper('Passwd');
		/*------------------------------------------------------------*/
		
		if(parent::isUpdatable())
		{
			$this->validate();
			$data = array(	'fk_category_seq'		=>	$this->fk_category_seq,
							'fk_user_seq'			=>	$this->fk_user_seq,
							'post_title'			=>	$this->post_title,
							'post_content'			=>	$this->post_content,
							'post_files'			=>	json_encode((array)$this->post_files),
							'post_secure_flag'		=>	$this->post_secure_flag,
							'post_notice_flag'		=>	$this->post_notice_flag,
							'post_tag'				=>	$this->post_tag,
							'post_option_field1'	=>	$this->post_option_field1,
							'post_option_field2'	=>	$this->post_option_field2,
							'post_option_field3'	=>	$this->post_option_field3,
							'post_option_field4'	=>	$this->post_option_field4,
							'post_option_field5'	=>	$this->post_option_field5,
							'post_poll_flag'		=>	$this->post_poll_flag,
							'post_poll_title'		=>	$this->post_poll_title,
							'post_poll_items'		=>	json_encode((array)$this->post_poll_items)
						);
			$dbo->update($data, array("post_seq = ".$this->post_seq));
			/******************************************************/
			parent::setBackupData(array_keys($data));
			$this->backup($log);
			/******************************************************/
		}
		$this->updateTag();
	}
	
	/**
	 * 
	 */
	public function delete($log='delete')
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$this->post_del_flag = 'T';
		$dbo->delete(array("post_seq = ".$this->post_seq));
		/******************************************************/
		parent::setBackupData();
		$this->backup($log);
		/******************************************************/
		
		//	게시판 정보 
		$bbs = Wdk::get('Bbs');
		$bbs->load($this->fk_bbs_seq);
		
		/******************************************************************
		 포인트 삭제
		*******************************************************************/	
		if($bbs['bbs_write_point'] > 0)
		{	
			$up = Wdk::get('UserPoint');
			$up->minus(	$this->fk_user_seq,
						$bbs['bbs_write_point'],
						"[".$bbs['bbs_name']."] 게시물 삭제 ($this->post_seq)"
						);
		}
		/*******************************************************************/
		$this->updateTag();
	}
	
	/**
	 * 
	 */
	public function read($post_seq=0, $bbs=null)
	{
		$this->load($post_seq, $bbs);
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$dbo->hit($this->post_seq);
		$this->post_hits++;
		
		//	게시판 정보
		$bbs = Wdk::get('Bbs');
		$bbs->load($this->fk_bbs_seq);
		
		/******************************************************************
			포인트 삭제
		*******************************************************************/
		if($bbs['bbs_read_point'] > 0)
		{	
			$up = Wdk::get('UserPoint');
			$up->minus(	$this->fk_user_seq,
						$bbs['bbs_read_point'],
						"[".$bbs['bbs_name']."] 게시물 삭제"
					);
		}
		/*******************************************************************/
	}
	
	/**
	 * 
	 */
	public function agree()
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$pr = Wdk::get('PostReact');
		$pr->agree($this->post_seq, $this->bbs['session']['user_seq']);
		$dbo->agree($this->post_seq);
		/******************************************************/
		parent::setBackupData();
		$this->backup("Agree");
		/******************************************************/
	}
	
	/**
	 * 
	 */
	public function opposite()
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$pr = Wdk::get('PostReact');
		$pr->opposite($this->post_seq, $this->bbs['session']['user_seq']);
		$dbo->opposite($this->post_seq);
		/******************************************************/
		parent::setBackupData();
		$this->backup("Opposite");
		/******************************************************/
	}
	
	/**
	 * 
	 */
	public function scrap()
	{
		if($this->isScrapable())
		{	
			$us = Wdk::get('UserScrap');
			$us['fk_post_seq'] = $this->post_seq;
			$us['fk_user_seq'] = $this->bbs['session']['user_seq'];
			$us->insert();
		}
	}
	
	/**
	 * 
	 */
	public function moveUp()
	{
		if($this->isMoveUpable())
		{
			/*------------------------------------------------------------*/
			$dbo = self::getDbo();
			/*------------------------------------------------------------*/
			$this->post_moveup_count++;
			$this->post_moveup_time	= mktime();
			$data = array(	'post_moveup_count'	=>	$this->post_moveup_count,
							'post_moveup_time'	=>	$this->post_moveup_time
						);
			$dbo->update($data, array("post_seq = ".$this->post_seq));
			/******************************************************/
			parent::setBackupData(array_keys($data));
			$this->backup("끌어올리기");
			/******************************************************/
		}
	}
	
	/**
	 * 
	 */
	public function report()
	{
		$pr = Wdk::get('PostReport');
		try
		{
			$pr->loadByPost($this->post_seq, $this->bbs['session']['user_seq']);
			throw new PostAlreadyReportedException();
		}
		catch(NoRecordException $e){}
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$pr = Wdk::get('PostReport');
		$pr->report($this->post_seq, $this->bbs['session']['user_seq']);
		$this->post_report_count++;
		$data = array(	'post_report_count'	=>	$this->post_report_count
						);
		$dbo->update($data, array("post_seq = ".$this->post_seq));
		/******************************************************/
		parent::setBackupData(array_keys($data));
		$this->backup("신고");
		/******************************************************/
	}
	
	
	/**
	*
	*/
	private function updateTag()
	{
		if(strlen(trim($this->post_tag)) > 0)
		{
			if($this->post_del_flag == 'T')
			{
				$ptm = Wdk::get('PostTagManager');
				$ptm->clearByPost($this->post_seq);
			}
			else
			{
				$tags = explode(',', $this->post_tag);
				if($this->post_insert_time == 0)
				{
					$pt = Wdk::get('PostTag');
					foreach($tags as $tag)
					{
						$pt['fk_post_seq'] = $this->post_seq;
						$pt['post_tag_name'] = trim($tag);
						$pt->insert();
					}
				}
				else
				{
					$tags = explode(', ', $this->post_tag);
					if(empty($tags) == false)
					{
						foreach($tags as $i=>$tag) $tags[$i] = trim($tag);
						$added		= array_diff($tags, $this->post_tags);
						$removed	= array_diff($this->post_tags, $tags);
						if(empty($added) == false)
						{
							foreach($added as $tag)
							{
								$pt = Wdk::get('PostTag');
								$pt['fk_post_seq'] = $this->post_seq;
								$pt['post_tag_name'] = trim($tag);
								$pt->insert();
							}
						}
						if(empty($removed) == false)
						{
							foreach($removed as $tag)
							{
								$pt = Wdk::get('PostTag');
								$pt->loadByName($this->post_seq, $tag);
								$pt->delete();
							}
						}
					}
				}
			}
		}
	}
	
	/**
	 *	
	 */
	private function validate()
	{
		if($this->bbs['bbs_poll_flag'] == 'T' && empty($this->post_poll_items) == false)
		{
			foreach($this->post_poll_items as $idx=>$item)
			{
				if(trim($item) == '') unset($this->post_poll_items[$idx]);
			}
			$this->post_poll_items = array_values($this->post_poll_items);
		}
		
		if(empty($this->bbs['bbs_option_fields']) == false)
		{
			foreach($this->bbs['bbs_option_fields'] as $i=>$field)
			{
				if($field['type'] == 'checkbox')
				{
					$name = 'post_option_field'.($i+1);
					$this->{$name} = json_encode($this->{$name});
				}
			}
		}
	}
	
	/**
	 *	
	 */
	private function backup($log='')
	{
		/*------------------------------------------------------------*/
		$dbo = self::getDbo();
		/*------------------------------------------------------------*/
		$dbo->log($this->post_seq, $log, $this->backup_data);
	}
	
	/**
	 * 
	 */
	public function getDbo()
	{
		return Wdk::model(substr(__CLASS__, 3));
	}
}